home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Sherlock 2.0
/
Mac v2.0 docs
/
Text Docs
/
Mac Macros .txt
< prev
next >
Wrap
Text File
|
1996-04-05
|
12KB
|
440 lines
Sherlock Macros
Overview
This chapter discusses all of Sherlock's macros. Sherlock’s macros expand into actual code only
if SHERLOCK is defined. The value assigned to the variable SHERLOCK does not matter, only
whether it is defined or not. Define SHERLOCK before including "sl.h".
Most Sherlock macros define tracepoints. Tracepoints are named locations within your program.
Tracepoints are either enabled or disabled. On the Macintosh, you enabled or disable tracepoints
either from a simulated command line or from the Sherlock menu. See the Chapter called
“Installing Sherlock” for full details.
Most Sherlock macros are tracing macros: these macros contain executable statements, called
tracepoint actions, which are executed when control reaches the macro, but only if the macro's
tracepoint has been enabled.
Tracepoint actions will often be tracing statements that print the values of various variables. On
the Macintosh, Sherlock creates and maintains a special window, called the log window, to which
traces are sent using the es family of routines. However, you can also use fprintf or any other
function to create traces.
Besides tracing macros, Sherlock contains several special-purpose macros. These macros do
tasks such as print or clear statistics, enable or disable watchpoints, or enable or disable
tracepoints at run time.
Macros such as STATB, TRACEPB and TICKB whose name ends in B denote entry macros.
These macros mark the start of timing sections. Similarly, macros whose name ends in X denote
exit macros that mark the end of timing sections.
Sherlock measures the time spent in all timing sections. Timing sections may be nested; Sherlock
maintains a timing stack describing all timing sections currently being executed. Each entry macro
must be paired with a corresponding exit macro with the same tracepoint name. If an exit macro is
omitted, a timing stack overflow will eventually result. If an extra exit macro is encountered, a
timing stack underflow may follow. Sherlock prints a warning message and a stack traceback
when either an overflow or an underflow is detected.
Sherlock also counts the number of time each macro was executed. These count statistics are
incremented even if a tracepoint is is disabled. Macros whose name ends in N do not update count
statistics.
Tracepoint Names
Tracepoint names may contain lower case letters, numerals and the underscore character, but not
blanks or special characters such as ( ) { } + etc. The following are valid tracepoint names:
STAT("rose");
STAT("rose25");
The following are invalid tracepoint names:
STAT("rose water"); // blank character
STAT("wine&roses"); // & character
Tracepoint names may start with a single minus sign. This minus sign indicates that the tracepoint
name may only be enabled explicitly, not with a wildcard. For instance, the following both define
the same tracepoint name, but tracing for the first statement must be enabled explicitly:
STAT("abc"); // may be enabled via wildcard such as ++a*
STAT("-abc"); // may only be enabled with ++abc
The FTAG, FTAGV and SL_NAME macros
The FTAG and FTAGV macros defines variables called ftag, ftagv, while the SL_NAME macro
defines a variable whose name you supply:
#define FTAG(s) char * ftag = s
#define FTAGV(s) char * ftagv = s
#define SL_NAME(name, s) char * name = s
Use one of these macros to define a tracepoint name used by several macros. This reduces the
number of strings used by Sherlock macros and also ensures that tracepoint names match. The
next section shows how to use the FTAG macro.
The STAT, STATB and STATX macros
STAT takes one argument, a tracepoint name. For example:
STAT("rose");
STAT produces no output; its only function is to provide a label for a count statistic.
The STATB is an entry macro that produces no output. Similarly, the STATX macro is an exit
macro that produces no output. For example, the following measures the time spent in a function:
int f()
{
FTAG("f");
declarations;
STATB(ftag);
body of f;
STATX(ftag);
}
The TICK, TICKB, TICKN and TICKX macros
The TICK macro takes one argument, a tracepoint name. Examples:
TICK(ftag);
TICK("marigold");
If enabled, TICK simply prints the name of the tracepoint followed by a colon. The output created
from the second example above would look like:
marigold:
TICK updates the count statistic associated with the tracepoint name. TICKN is the same as TICK
except that it does not update the count statistic.
The TICKB and TICKX macros are the corresponding entry and exit macros. TICKB updates
count statistics; TICKX does not.
The TRACE, TRACEB, TRACEN and TRACEX macros
TRACE takes two arguments. The first is a tracepoint name. The second is a list of tracepoint
actions, consisting of one or more C language statements or blocks. Statements in the list of
tracepoint actions are separated by semicolons as usual. For example:
TRACE(ftag, es("variable v = "); eint(v); enl());
The tracepoint actions consist of three statements:
es("variable v = "); eint(v); enl();
The tracepoint actions will be executed only if the string contained in the ftag variable has been
enabled. Any number of C statements may appear in the list of tracepoint actions. For example:
TRACE(ftag,
struct s * p=f(arg);
print_s(p); enl();
);
The tracepoint action consist of the following 3 statements:
struct s * p=f(arg);
print_s(p); enl();
You can write any C statements in the list of tracepoint actions except initializers containing curly
braces. Tracepoint actions may even contain other macros. For example:
TRACE("abc"
TRACE("xyz",
es("abc and xyz both enabled\n")));
The TRACEB, TRACEN and TRACEX macros work as you would expect: the TRACEN macro
does not update count statistics, the TRACEB macro is an entry macro and the TRACEX macro is
an exit macro.
The TRACEP, TRACEPB, TRACEPN and TRACEPX macros
The TRACEP macro works just like the TRACE macro except that TRACEP prints the name of
the tracepoint, a colon and a space before executing the tracepoint actions. For example, the
following two macros are equivalent:
TRACE("daisy", es("daisy: n = "); eint(n); enl());
TRACEP("daisy", es("n = "); eint(n); enl());
Similarly, the TRACEPB, TRACEPN, and TRACEPX macros works like the corresponding
TRACEB, TRACEN and TRACEX macros except that they print the name of the tracepoint before
executing their tracepoint actions.
There are no macros names TRACEBP, TRACEXP, etc. Think of TRACEP as a separate family
from TRACEP; the P is not a suffix than can be applied to any macro.
The SL_DUMP and SL_CLEAR macros
The SL_DUMP macro prints out a report of all statistics gathered so far. It takes no arguments
and can be called at any time. For example:
SL_DUMP();
The report contains several columns. The tracepoints column is an alphabetized list of tracepoint
names, the ticks column gives count statistics for each tracepoint name, the times1 column gives
non-cumulative timing statistics, the times2 column gives cumulative timing statistics and the
tracing column indicates whether the tracepoint was enabled at the time SL_DUMP was called.
The SL_CLEAR macro zeros all statistics. The SL_INIT macro also does this, so normally there
is no need to use this macro. You might use this macro to begin gathering statistics about a
selected portion of your code. Call SL_CLEAR at the start of the section and SL_DUMP at the
end of the section.
The SL_ON and SL_OFF macros
These macros enable or disable the tracing for a single tracepoint, just as if the name of the
tracepoint were appended to the end of the command line. Wildcard characters and disable counts
are allowed.
The name “trace” is a special case which enables or disables the tracing of all tracepoints.
SL_OFF( "trace") is faster than disabling tracing for all tracepoints using wildcards because
SL_OFF("trace") disables all tracing logic. Examples:
SL_ON("abc");
SL_OFF("*");
SL_OFF("trace"); // enables all tracing logic
The SL_INIT and SL_PARSE macros
The SL_INIT macro should be executed before any other macro. It initializes the Sherlock
system. SL_INIT should also be called before the w_mac_init routine. The SL_PARSE macro
reads an argv vector looking for Sherlock arguments. Examples:
SL_INIT();
SL_PARSE(argc, argv, "++", "--");
The "++" and "--" arguments are the prefix strings used to distinguish Sherlock arguments from
other arguments. See the Chapter called “Installing Sherlock” for full details.
The SL_WATCH macro
The SL_WATCH macro specifies the starting address and length of a block. This block is checked
whenever a sherlock macro is executed and a messages is issued whenever the block changes.
This macro takes three arguments: the address of the first byte of the block, the length of the
block, and a string to print in the warning message. For instance, the following watch macro
checks to see if any NULL pointer has been used to store data.
SL_WATCH((char *) 0, 4, "location zero");
The SL_DISABLE and SL_ENABLE macros
Use the SL_ENABLE and SL_DISABLE macros for greater control over SPP. Neither macro
generates any code—they simply serve as markers for SPP. SL_DISABLE causes SPP not to
generate macros for a function. For example,
int f(void)
{
declarations;
SL_DISABLE();
// SPP will not generate Sherlock macros in this function.
}
The FTAG macro also will cause SPP not to generate macros for a function:
int f(void)
{
FTAG("f");
declarations;
// SPP will not generate Sherlock macros in this function.
}
The SL_ENABLE macros forces SPP to insert macros into a function. Use this macro when a
function starts with a Sherlock macro that you wrote yourself. For example:
int g(void)
{
declarations;
SL_ENABLE();
TRACEP("dump", es("g = "); eint(g); enl());
// SPP will generate Sherlock macros in this function.
}
Summary of Sherlock macros
SL_INIT(); SL_PARSE(argc, argv, "++", "--");
SL_INIT initializes the Sherlock system. SL_PARSE enables or disables tracepoints.
FTAG(string); FTAGV(string);
SL_NAME(name, string);
FTAG and FTAGV define a variables named ftag and ftagv initialized to the given string.
SL_NAME defines a variable with the given name initialized to the given string.
STAT(tracepoint);
STATB(tracepoint);
STATX(tracepoint);
The STAT macros increment their count statistic but produce no output.
TICK(tracepoint);
TICKB(tracepoint);
TICKN(tracepoint);
TICKX(tracepoint);
The TICK macros print the name of the tracepoint.
TRACE(tracepoint, statements); TRACEP(tracepoint, statements);
TRACEB(tracepoint, statements); TRACEPB(tracepoint, statements);
TRACEN(tracepoint, statements); TRACEPN(tracepoint, statements);
TRACEX(tracepoint, statements); TRACEPX(tracepoint, statements);
The TRACE macros execute their statements only if their tracepoints are enabled. The TRACEP
macros print their tracepoint name and execute their statements only if their tracepoints are enabled.
SL_CLEAR(); SL_DUMP();
SL_CLEAR clears all statistics. SL_DUMP prints a report of all statistics.
SL_ON(tracepoint); SL_OFF(tracepoint);
SL_ON enables tracing for the tracepoint. SL_OFF disables tracing for a single tracepoint.
SL_OFF("trace") disables all tracing.
SL_ENABLE(); SL_DISABLE();
SL_DISABLE prevents SPP from generating macros. SL_ENABLE forces SPP to generate
macros.
SL_WATCH(block, block, tag);
SL_WATCH check the block on all Sherlock calls and reports when the block changes.